﻿using AgencyManagerSystem.Common;
using AgencyManagerSystem.DataFetcher;
using AgencyManagerSystem.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Reflection;
using System.Linq;
using System.Threading.Tasks;
using AgencyManagerSystem.Core.Utility;

namespace AgencyManagerSystem.Core
{
    public class JwtTokenValidata 
    {
        public void BindRightTable(AuthorizationOptions authorizationOptions)
        {
            AuthorizationPolicyBuilder myAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder();
            authorizationOptions.AddPolicy(Definer.POLICY_NAME, policy=>policy.AddRequirements(new RightTableAuthorizationRequirement()));
        }
    }
    public class RightTableAuthorizationRequirement : IAuthorizationRequirement
    {

    }
    public class RightTableAuthorizationHandler : AuthorizationHandler<RightTableAuthorizationRequirement>
    {
        private bool CompareDomain(int domain, PolicyDomain policyDomain)
        {
            DomainFetcher domainFetcher = new DomainFetcher();
            DomainModel domainModel = domainFetcher.Get(domain);
            if (domainModel == null)
            {
                return false;
            }
            int[] super = { Definer.DOMAIN_SUPER };
            int[] center = { Definer.DOMAIN_SUPER, Definer.DOMAIN_CENTER };
            int[] site = { Definer.DOMAIN_SUPER, Definer.DOMAIN_CENTER, Definer.DOMAIN_SITE };
            int[] suppiler = { Definer.DOMAIN_SUPER, Definer.DOMAIN_CENTER, Definer.DOMAIN_SUPPILER };
            int domainType = domainModel.Type;
            return policyDomain == PolicyDomain.Super && super.Contains(domainType)
                || policyDomain == PolicyDomain.Center && center.Contains(domainType)
                || policyDomain == PolicyDomain.Retail && site.Contains(domainType)
                || policyDomain == PolicyDomain.Supplier && suppiler.Contains(domainType)
                || policyDomain == PolicyDomain.Ignore;
        }
        private bool CompareRightTable(int uid,int domain,int module,AppOpt appOpt)
        {
            if (uid == 1)
            {
                LogHelper.Log(this.GetType().Name, String.Format("模块{0}授权用户{1}成功", uid, module));
                return true;
            }
            LoginFetcher loginFetcher = new LoginFetcher();
            string message;
            RoleTableModel rightTableModel = loginFetcher.GetRightTableByLogin(uid, domain,module, out message);
            if (appOpt == AppOpt.Create && rightTableModel.Create
                || appOpt == AppOpt.Approve && rightTableModel.Approve
                || appOpt == AppOpt.Delete && rightTableModel.Delete
                || appOpt == AppOpt.Exec && rightTableModel.Exec
                || appOpt == AppOpt.Func1 && rightTableModel.Func1
                || appOpt == AppOpt.Func2 && rightTableModel.Func2
                || appOpt == AppOpt.Func3 && rightTableModel.Func3
                || appOpt == AppOpt.Func4 && rightTableModel.Func4
                || appOpt == AppOpt.UnApprove && rightTableModel.UnApprove)
            {
                LogHelper.Log(this.GetType().Name, String.Format("模块{0}授权用户{1}成功", uid,module));
                return true;
            }
            else
            {
                LogHelper.Err(this.GetType().Name, String.Format("模块{0}授权用户{1}失败", uid, module));
                return false;
            }
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RightTableAuthorizationRequirement requirement)
        {
            if (context.Resource is AuthorizationFilterContext mvc)
            {
                ControllerActionDescriptor controllerActionDescriptor = mvc.ActionDescriptor as ControllerActionDescriptor;
                string module = controllerActionDescriptor.ControllerName;
                RoleFlagAuthorizeAttributeAttribute rightFlagAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttribute<RoleFlagAuthorizeAttributeAttribute>();
                if(rightFlagAttribute!=null)
                {
                    string access = "";
                    MyHttpContextHelper.SetHttpContext(out access);
                    UserProfile user = MyHttpContext.Current.Items[Definer.CURRENT_PROFILE] as UserProfile;
                    ModuleFetcher moduleFetcher = new ModuleFetcher();
                    ModuleModel moduleModel = moduleFetcher.GetByCode(module);
                    if (user != null && moduleModel != null)
                    {
                        if(CompareDomain(user.Domain,rightFlagAttribute.DomainPolicy)&&CompareRightTable(user.UserId,user.Domain,moduleModel.AutoId,rightFlagAttribute.Opt))
                        {
                            context.Succeed(requirement);
                        }
                        else
                        {
                            context.Fail();
                        }
                    }
                    else
                    {
                        LogHelper.Err(this.GetType().Name, String.Format("系统内部异常，找不到用户信息或模块信息"));
                        context.Fail();
                    }
                }
            }
            return Task.CompletedTask;
        }
    }
}
